package models

import (
	"gitchina/kly_service/data"
	"gitchina/kly_service/errors"
	"gitchina/kly_service/util"
)

type InvoicePostAddr struct {
	Id            ID     `json:"id"`
	Title         string `json:"title"`
	Addr          string `json:"post_addr"`
	TaxNo         string `json:"tax_no"`
	RecvName      string `json:"recv_name"`
	ZipCode       string `json:"zip_code"`
	RecvPhone     string `json:"recv_phone"`
	BankOfDeposit string `json:"bank_of_deposit"`
	BankCardNo    string `json:"bank_card_no"`
}

type InvoiceInfo struct {
	Title         string  `json:"title"`
	Addr          string  `json:"addr"`
	RecvName      string  `json:"recv_name"`
	ZipCode       string  `json:"zip_code"`
	RecvPhone     string  `json:"recv_phone"`
	TaxNo         string  `json:"tax_no"`
	Amount        float32 `json:"amount"`
	InvoiceCorp   string  `json:"invoice_corp"`
	BankOfDeposit string  `json:"bank_of_deposit"`
	BankCardNo    string  `json:"bank_card_no"`
	WaybillId     string  `json:"waybill_id,omitempty"`
}

func (l Logistics) AddInvoicePostAddr(mbrId ID, rq *InvoicePostAddr) (invoiceAddrId ID, err error) {
	var id int64
	if _, _, _, id, err = mbrId.Decode(); err != nil {
		err = errors.New(errors.MSG_Mbr_Invalid)
	} else {
		var repo data.LogisticsRepo
		if id, err = repo.AddInvoiceAddr(&data.InvoiceAddrDto{
			MemberId:      int(id),
			Title:         rq.Title,
			Addr:          rq.Addr,
			RecvName:      rq.RecvName,
			ZipCode:       rq.ZipCode,
			RecvPhone:     rq.RecvPhone,
			TaxNo:         rq.TaxNo,
			BankOfDeposit: rq.BankOfDeposit,
			BankCardNo:    rq.BankCardNo,
		}); err != nil {
			util.GetLogger().Error("[model-AddInvoicePostAddr] - error:%s", err.Error())
			err = errors.New(errors.MSG_Logi_Too_Many_Invoice_Addrs)
		} else {
			invoiceAddrId.Encode(ID_Shard, ID_Ver, ID_InvoiceAddr_Category, id)
		}
	}
	return
}

func (l Logistics) UpdateInvoicePostAddr(mbrId ID, rq *InvoicePostAddr) (err error) {
	var mId, invoiceAddrId int64
	var repo data.LogisticsRepo
	if _, _, _, mId, err = mbrId.Decode(); err != nil {
		err = errors.New(errors.MSG_Mbr_Invalid)
	} else {
		if _, _, _, invoiceAddrId, err = rq.Id.Decode(); err != nil {
			err = errors.New(errors.MSG_Logi_Invalid_Invoice_Addr_ID)
		} else {
			if err = repo.UpdateInvoiceAddr(int(mId), &data.InvoiceAddrDto{
				Id:            int(invoiceAddrId),
				Title:         rq.Title,
				RecvName:      rq.RecvName,
				Addr:          rq.Addr,
				ZipCode:       rq.ZipCode,
				RecvPhone:     rq.RecvPhone,
				TaxNo:         rq.TaxNo,
				BankOfDeposit: rq.BankOfDeposit,
				BankCardNo:    rq.BankCardNo,
			}); err != nil {
				util.GetLogger().Error("[model-UpdateInvoicePostAddr] - error:%s", err.Error())
				err = nil
			}
		}

	}
	return err
}

func (l Logistics) DeleteInvoicePostAddr(mbrId, invoiceAddrId ID) (err error) {
	var mId, addrId int64
	var repo data.LogisticsRepo
	if _, _, _, mId, err = mbrId.Decode(); err != nil {
		err = errors.New(errors.MSG_Mbr_Invalid)
		return
	}

	if _, _, _, addrId, err = invoiceAddrId.Decode(); err != nil {
		err = errors.New(errors.MSG_Logi_Invalid_Invoice_Addr_ID)
		return
	}

	if err = repo.DeleteInvoiceAddr(int(mId), int(addrId)); err != nil {
		util.GetLogger().Error("[model-DeleteInvoicePostAddr] - error:%s", err.Error())
		err = nil
	}
	return

}

func (l Logistics) GetInvoicePostAddrs(mbrId ID) (rs []InvoicePostAddr) {
	var err error
	var id int64
	if _, _, _, id, err = mbrId.Decode(); err != nil {
		err = errors.New(errors.MSG_Mbr_Invalid)
	} else {
		var repo data.LogisticsRepo
		if list, err := repo.GetInvoiceAddrs(int(id)); err != nil {
			util.GetLogger().Error("[model-GetInvoiceAddrs] - error:%s", err.Error())
		} else {
			rs = make([]InvoicePostAddr, len(list))
			for idx, dto := range list {
				var invoiceAddrId ID
				invoiceAddrId.Encode(ID_Shard, ID_Ver, ID_InvoiceAddr_Category, int64(dto.Id))
				rs[idx] = InvoicePostAddr{
					Id:            invoiceAddrId,
					Title:         dto.Title,
					Addr:          dto.Addr,
					RecvName:      dto.RecvName,
					ZipCode:       dto.ZipCode,
					RecvPhone:     dto.RecvPhone,
					TaxNo:         dto.TaxNo,
					BankOfDeposit: dto.BankOfDeposit,
					BankCardNo:    dto.BankCardNo,
				}
			}
		}
	}

	return
}

func (l Logistics) GetLastInvoicePostAddr(mbrId ID) (rs InvoicePostAddr) {
	var err error
	var id int64
	var repo data.LogisticsRepo
	if _, _, _, id, err = mbrId.Decode(); err != nil {
		err = errors.New(errors.MSG_Mbr_Invalid)
	} else {
		if dto, err := repo.GetLastInvoiceAddr(int(id)); err == nil {
			var invoiceAddrId ID
			invoiceAddrId.Encode(ID_Shard, ID_Ver, ID_InvoiceAddr_Category, int64(dto.Id))
			rs = InvoicePostAddr{
				Title:         dto.Title,
				Addr:          dto.Addr,
				RecvName:      dto.RecvName,
				ZipCode:       dto.ZipCode,
				RecvPhone:     dto.RecvPhone,
				TaxNo:         dto.TaxNo,
				BankOfDeposit: dto.BankOfDeposit,
				BankCardNo:    dto.BankCardNo,
			}
		} else {
			util.GetLogger().Error("[model-GetLastInvoiceAddr] - error:%s", err.Error())
		}
	}

	return
}

func (l Logistics) CanUseInvoice(mbrId ID) (ok bool, err error) {
	var id int64
	var mbr Member
	var rs CargoOwnerRS
	var mbrType string
	var mbrRepo data.MemberRepo
	if _, _, _, id, err = mbrId.Decode(); err != nil {
		err = errors.New(errors.MSG_Mbr_Invalid)
	} else {
		if mbrType, err = mbrRepo.GetMemberType(int(id)); err == nil {
			if mbrType == "1" {
				if rs, err = mbr.GetCargoOwner(mbrId); err == nil {
					ok = rs.IsCorp
				}
			} else {
				ok = true
			}
		}
	}
	return
}
